/*
 * Copyright (c) 2018, apexes.net. All rights reserved.
 *
 *         http://www.apexes.net
 *
 */
package net.apexes.demo.query;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.stmt.UpdateBuilder;
import com.j256.ormlite.support.ConnectionSource;
import net.apexes.commons.lang.Enume;
import net.apexes.commons.lang.IDs;
import net.apexes.commons.ormlite.DatabaseHelper;
import net.apexes.demo.codegen.entity.enums.PayType;
import net.apexes.demo.codegen.entity.enums.StatusFlag;
import net.apexes.demo.codegen.enume.support.DemoEnumeSupport;
import net.apexes.demo.codegen.ormlite.column.QPay;
import net.apexes.demo.codegen.ormlite.entity.Pay;
import net.apexes.demo.codegen.util.DemoDatabases;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @author <a href="mailto:hedyn@foxmail.com">HeDYn</a>
 *
 */
public class OrmliteDemo {
    
    public static void main(String[] args) throws Exception {
        ConnectionSource connSource = DemoDatabases.createConnectionSource();
        testSelect(connSource);
        testUpdate(connSource);
    }
    
    static void testSelect(ConnectionSource connSource) throws Exception {
        ObjectMapper mapper = DemoEnumeSupport.getInstance().createObjectMapper();
        Gson gson = DemoEnumeSupport.getInstance().createGsonBuilder().create();

        DatabaseHelper helper = new OrmliteDemoDatabaseHelper(connSource);
        Dao<Pay, String> dao = helper.dao(QPay.$);

        Pay cashPay = cratePayByCash(StatusFlag.VALID);
        dao.create(cashPay);

        List<Pay> payList = dao.queryForAll();
        for (Pay pay : payList) {
            PayType type = pay.getPayType();
            System.out.println(" ---- " + type + "(" + (type==null?"null":type.value())+")");
            String json = mapper.writeValueAsString(pay);
            System.out.println("jackson: " + json);
            Pay temp = mapper.readValue(json, Pay.class);
            System.out.println("jackson: " + mapper.writeValueAsString(temp));
            json = gson.toJson(temp);
            System.out.println("gson: " + json);
            temp = gson.fromJson(json, Pay.class);
            System.out.println("gson: " + gson.toJson(temp));
        }
        
        System.out.println("=============================");

        payList = dao.queryForEq(QPay.$.statusFlag.name(), StatusFlag.VALID);
        for (Pay pay : payList) {
            PayType type = pay.getPayType();
            System.out.println(" ---- " + type + "(" + (type==null?"null":type.value())+")");
            String json = mapper.writeValueAsString(pay);
            System.out.println("jackson: " + json);
            Pay temp = mapper.readValue(json, Pay.class);
            System.out.println("jackson: " + mapper.writeValueAsString(temp));
            json = gson.toJson(temp);
            System.out.println("gson: " + json);
            temp = gson.fromJson(json, Pay.class);
            System.out.println("gson: " + gson.toJson(temp));
        }

    }

    static void testUpdate(ConnectionSource connSource) throws Exception {
        ObjectMapper mapper = DemoEnumeSupport.getInstance().createObjectMapper();
        Gson gson = DemoEnumeSupport.getInstance().createGsonBuilder().create();

        DatabaseHelper helper = new OrmliteDemoDatabaseHelper(connSource);
        Dao<Pay, String> dao = helper.dao(QPay.$);

        String id = null;
        List<Pay> payList = dao.queryForEq(QPay.$.statusFlag.name(), StatusFlag.VALID);
        for (Pay pay : payList) {
            PayType type = pay.getPayType();
            System.out.println(" ---- " + type + "(" + (type==null?"null":type.value())+")");
            String json = mapper.writeValueAsString(pay);
            System.out.println("jackson: " + json);
            Pay temp = mapper.readValue(json, Pay.class);
            System.out.println("jackson: " + mapper.writeValueAsString(temp));
            json = gson.toJson(temp);
            System.out.println("gson: " + json);
            temp = gson.fromJson(json, Pay.class);
            System.out.println("gson: " + gson.toJson(temp));

            id = pay.getId();
        }

        if (id != null) {
            System.out.println("update to INVALID =============================");
            UpdateBuilder<Pay, String> updateBuilder = dao.updateBuilder();
            updateBuilder.updateColumnValue(QPay.$.statusFlag.name(), StatusFlag.INVALID)
                    .where().eq(QPay.$.id.name(), id);
            updateBuilder.update();

            Pay pay = dao.queryForId(id);
            String json = mapper.writeValueAsString(pay);
            System.out.println("jackson: " + json);

            System.out.println("update to VALID =============================");

            updateBuilder.reset();
            updateBuilder.updateColumnValue(QPay.$.statusFlag.name(), StatusFlag.VALID)
                    .where().eq(QPay.$.id.name(), id);
            updateBuilder.update();

            pay = dao.queryForId(id);
            json = mapper.writeValueAsString(pay);
            System.out.println("jackson: " + json);

            pay.setId(IDs.newId());
            dao.create(pay);
            dao.update(pay);
        }

    }

    static Pay cratePayByCash(StatusFlag statusFlag) {
        return createPay(statusFlag, PayType.CASH);
    }

    static Pay cratePayByUnknown(StatusFlag statusFlag, String value) {
        PayType payType = Enume.fromValue(PayType.class, value);
        return createPay(statusFlag, payType);
    }

    static Pay createPay(StatusFlag statusFlag, PayType payType) {
        Pay pay = new Pay();
        pay.setId(IDs.newId());
        pay.setAllowChange(true);
        pay.setAllowFavoured(true);
        pay.setCrtTime(LocalDateTime.now());
        pay.setCrtWho("admin");
        pay.setName("现金");
        pay.setPayType(payType);
        pay.setDefaultValue(null);
        pay.setStatusFlag(statusFlag);
        pay.setVersion("000");
        pay.setTemplateId(QuerydslDemo.TEMPLATE_ID);
        return pay;
    }
}
